﻿using Microsoft.Extensions.Configuration;
using System;
using System.Net.Http;
using SSharing.Frameworks.NetCore.Common.Extends;
using Microsoft.Extensions.Logging;
using FeiShu.Entity.Adapter.FeiShuWork;
using Polly;
using System.Threading.Tasks;
using System.Text;
using System.Net.Http.Headers;

namespace FeiShu.Adapter
{
    public class FeiShuWorkAdapter
    {
        private readonly IHttpClientFactory _clientFactory;
        private readonly ILogger _logger;
        private readonly string FeiShuAppId;
        private readonly string FeiShuAppSecret;
        private readonly string FeiShuApiHost;

        public FeiShuWorkAdapter(IHttpClientFactory httpClientFactory, ILogger logger)
        {
            _clientFactory = httpClientFactory;
            _logger = logger;
            IConfigurationBuilder builder = new ConfigurationBuilder();
            builder.AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);//reloadOnChange:true当配置更新了程序自动更新
            builder.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true);
            IConfigurationRoot configRoot = builder.Build();
            var qywxSection = configRoot.GetSection("FEISHU");
            FeiShuAppId = qywxSection["AppID"];
            FeiShuAppSecret = qywxSection["AppSecret"];
            FeiShuApiHost = qywxSection["ApiHost"].TrimEnd(new char[] { '/' });
        }

        private HttpClient HttpClient
        {
            get
            {
                var httpClient = _clientFactory.CreateClient();
                return httpClient;
            }
        }

        public AccessTokenResponse GetAccessToken()
        {
            var getTokenUrl = string.Format("{0}/open-apis/auth/v3/app_access_token/internal", FeiShuApiHost);
            return PostAsync<AccessTokenResponse>(getTokenUrl, new AccessTokenRequest() { app_id = FeiShuAppId, app_secret = FeiShuAppSecret }).Result;
        }

        public UserAccessTokenResponse GetUserAccessToken(string appAccessToken,string code)
        {
            var getTokenUrl = string.Format("{0}/open-apis/authen/v1/access_token", FeiShuApiHost);

            HttpRequestMessage formData = new HttpRequestMessage(HttpMethod.Post, getTokenUrl);
            formData.Headers.Authorization = new AuthenticationHeaderValue("Bearer", appAccessToken);
            formData.Content = new StringContent(new UserAccessTokenRequest() { code = code, grant_type = "authorization_code" }.ToJson(), Encoding.UTF8, "application/json");
            
            return PostAsync<UserAccessTokenResponse>(getTokenUrl, formData).Result;
        }



        private async Task<T> PostAsync<T>(string requestUri, object param)
        {
            HttpResponseMessage httpResponse = null;
            try
            {
                httpResponse = await HttpClient.PostAsync(requestUri, new StringContent(param.ToJson(), Encoding.UTF8, "application/json"));
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
            }

            if (httpResponse?.IsSuccessStatusCode == false)
            {
                return default(T);
            }

            var json = await httpResponse.Content.ReadAsStringAsync();
            _logger.LogInformation($"{requestUri} {json}");
            return json.FromJson<T>();
        }

        private async Task<T> PostAsync<T>(string requestUri, HttpRequestMessage param)
        {
            HttpResponseMessage httpResponse = null;
            try
            {
                httpResponse = await HttpClient.SendAsync(param);
            }
            catch (Exception e)
            {
                _logger.LogError(e, e.Message);
            }

            if (httpResponse?.IsSuccessStatusCode == false)
            {
                return default(T);
            }

            var json = await httpResponse.Content.ReadAsStringAsync();
            _logger.LogInformation($"{requestUri} {json}");
            return json.FromJson<T>();
        }
    }
}
